
#include <rtdef.h>
#include <rtthread.h>
#include <rthw.h>

#include "PRINT/my_printf.h"

#include "LED/led.h"
#include "KEY/key.h"
#include "UART/uart.h"
#include "PLL/pll.h"
#include "PRINT/my_printf.h"
#include "VIC/vic_reg.h"
#include "INIT/init.h"
#include "EXTI/exti.h"
#include "TIMER/timer.h"
#include "SDIO/sdio.h"
#include "PUBLIC/test.h"
#include "PUBLIC/public.h"


struct rt_thread *rt_flag1_thread;
struct rt_thread *rt_flag2_thread;
struct rt_thread *rt_flag3_thread;

rt_uint8_t rt_flag1_thread_stack[2048];
rt_uint8_t rt_flag2_thread_stack[2048];
rt_uint8_t rt_flag3_thread_stack[512];

extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
extern u32 PendSV_Handler;
extern rt_uint32_t rt_thread_switch_interrupt_flag;
extern rt_uint32_t rt_interrupt_to_thread;

extern rt_tick_t rt_tick;

static rt_sem_t sem;

void delay(int t){
    for(; t != 0; t--);
}

void flag1_thread_entry(void *p_arg){
    printf("flag1_thread_entry %d\r\n", (int)rt_tick);

    while(1){
        rt_sem_take(sem, RT_WAITING_FOREVER);   // 
        printf("flag1 take a sem.%c\r\n\r\n", ' ');
    }
}

void flag2_thread_entry(void *p_arg){
    rt_int32_t num = 0;

    printf("flag2_thread_entry %d\r\n", (u32)rt_tick);
    
    while(1){
        printf("flag2 release a sem. %d\r\n", num);
        rt_sem_release(sem);
        num++;
        
        rt_thread_delay(50);
    }
}

void flag3_thread_entry(void *p_arg){

    while(1){
        led1_on();
        rt_thread_delay(50);

        led1_off();
        rt_thread_delay(50);
    }
}

void semaphore_init(){
    sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
    if(sem == RT_NULL){
        printf("create dynamic semaphore failed! %c\r\n", ' ');
    }else{
        printf("create done! %c\r\n", ' ');
    }

}

void my_log(u32 r0, u32 r1){
    u32 fp, sp, lr, cpsr;

    __asm__(
        "mov %0, fp\n"
        "mov %1, sp\n"
        "mov %2, lr\n"
        "mrs %3, cpsr\n"
        :"=r"(fp), "=r"(sp), "=r"(lr), "=r"(cpsr)
    );
    printf("log fp:%x sp:%x lr:%x cpsr:%x\r\n", fp, sp, lr, cpsr);

}

void log_thread(struct rt_thread *r0){
    printf("%08x\r\n", (u32)r0->sp);
    printf("%08x\r\n", (u32)r0->stack_addr);
    printf("%08x\r\n", (u32)r0->stack_size);
    printf("%08x\r\n", (u32)r0->entry);
    printf("%08x\r\n", (u32)r0->parameter);
    printf("%08x\r\n", (u32)&r0->tlist);
}

int main(){
    
    /* 关中断 */
    rt_hw_interrupt_disable();

    vic_init(63, (u32)&PendSV_Handler); // 调度中断
    led_init();
    key_init();
    
    /* 设置SysTick中断频率 */
    SysTick_Config();

    /* 系统定时器列表初始化 */
    rt_system_timer_init();
    
    /* 初始化系统调度器 */
    rt_system_scheduler_init();

    /* 初始化空闲线程 */    
    rt_thread_idle_init();

    semaphore_init();

    /* 初始化线程 */
    rt_flag1_thread = rt_thread_create("thread1", flag1_thread_entry, RT_NULL, 2048, 2, 10);
    rt_thread_startup(rt_flag1_thread);    // 启动线程，但是并不会被立即执行
    
    rt_flag2_thread = rt_thread_create("thread2", flag2_thread_entry, RT_NULL, 2048, 3, 10);
    rt_thread_startup(rt_flag2_thread);

    rt_flag3_thread = rt_thread_create("thread3", flag3_thread_entry, RT_NULL, 2048, 3, 5);
    rt_thread_startup(rt_flag3_thread);
    
    rt_system_scheduler_start();
    
    return 0;
}


void SysTick_Handler(void)
{
    /* 进入中断 */
    rt_interrupt_enter();

    rt_tick_increase();

    TINT_CSTAT |= (1 << 5); // 清除中断标志

    /* 离开中断 */
    rt_interrupt_leave();
}
